using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using snat.algorithms;

namespace algorithms {
    public sealed partial class AlgorithmSet : IEnumerable<KeyValuePair<String, IAlgorithm>> {

        public IAlgorithm this[String algorithmName] {
            get {
                return Instance.Algorithms[algorithmName];
            }
        }

        private static volatile AlgorithmSet instance = new AlgorithmSet();
        public static AlgorithmSet Instance {
            get {
                return instance;
            }
        }

        private Dictionary<String, IAlgorithm> Algorithms;
        public void Add(String name, IAlgorithm algorithm) {
            int i = 1;
            while (Algorithms.ContainsKey(name)) {
                if (i > 1) {
                    name.Remove(name.Length - (i-1).ToString().Length);
                }
                name += i.ToString();
                i++;
            }
            Algorithms.Add(name, algorithm);
        }

        private AlgorithmSet() {
            Algorithms = new Dictionary<String, IAlgorithm>();
        }

        public void Init() {
            Algorithms.Clear();
            try {
                UserInit();
            } catch (ArgumentException ex) {
                throw new AlgorithmNameException(@"There are two algorithms initialized in 
                                                 AlgorithmSet.UserInit() which have the same Name", ex);
            }
        }


        public bool TryRegister(String alg) {
            if (Algorithms.ContainsKey(alg)) {
                Algorithms[alg].Register();
                return true;
            } else {
                return false;
            }
        }

        public bool TryDeRegister(String alg) {
            if (Algorithms.ContainsKey(alg)) {
                Algorithms[alg].DeRegister();
                return true;
            } else {
                return false;
            }
        }

        public IEnumerator<KeyValuePair<String, IAlgorithm>> GetEnumerator() {
            foreach (KeyValuePair<String, IAlgorithm> a in Algorithms) {
                yield return a;
            }
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
            return GetEnumerator();
        }
    }
}
